#include "collider-base.h"
#include "../math/vec3.h"
#include "../geometry/aabb.h"
#include "../scene/node.h"
#include "./physics.h"
#include "../log.h"
/**
 * 碰撞组件基类
 */
ColliderBase::ColliderBase(Node *node) : _node(node), _group(1), _mask(-1), _type(PhysicsColliderType::STATIC)
{
    this->_aabb = new AABB();
    Physics::colliders.insert(std::make_pair(node->getID(), this));
    this->_updateTransform();
}
AABB *ColliderBase::getAABB()
{
    return this->_aabb;
}
Node *ColliderBase::getNode()
{
    return this->_node;
}
void ColliderBase::setGeometry(PhysicsColliderGeometry geometry)
{
    this->_geometry = geometry;
}
PhysicsColliderGeometry ColliderBase::getGeometry()
{
    return this->_geometry;
}

void ColliderBase::setGroup(int group)
{
    this->_group = group;
}
void ColliderBase::setMask(int mask)
{
    this->_mask = mask;
}
int ColliderBase::getGroup()
{
    return this->_group;
}
int ColliderBase::getMask()
{
    return this->_mask;
}
void ColliderBase::setType(PhysicsColliderType type)
{
    this->_type = type;
}
PhysicsColliderType ColliderBase::getType()
{
    return this->_type;
}
void ColliderBase::addRef()
{
    this->_ref += 1;
}
void ColliderBase::cleanRef()
{
    this->_ref = 0;
}
void ColliderBase::update(float dt)
{
    // Log::print("刷新碰撞组件...."+this->_ref);
    this->_updateTransform();
}
void ColliderBase::_updateTransform()
{
    if (this->_ref <= 0)
        return;
    this->_ref = 0;

    this->_aabb->transform(this->_node->getPosition(), this->_node->getScale(), this->_node->getRotation());
    // Log::print("" + (this->_node->getID()) + "节点，刷新碰撞参数 centerX:" + std::to_string(this->_aabb->getCenter().getX()));
    // Log::print("" + (this->_node->getID()) + "节点，刷新碰撞参数 centerY:" + std::to_string(this->_aabb->getCenter().getY()));
    // Log::print("" + (this->_node->getID()) + "节点，刷新碰撞参数 centerZ:" + std::to_string(this->_aabb->getCenter().getZ()));
    // Log::print("" + (this->_node->getID()) + "节点，刷新碰撞参数 hX:" + std::to_string(this->_aabb->getHalfExtents().getX()));
    // Log::print("" + (this->_node->getID()) + "节点，刷新碰撞参数 hY:" + std::to_string(this->_aabb->getHalfExtents().getY()));
    // Log::print("" + (this->_node->getID()) + "节点，刷新碰撞参数 hZ:" + std::to_string(this->_aabb->getHalfExtents().getZ()));
}
// 添加碰撞回调
#ifdef __EMSCRIPTEN__
void ColliderBase::setColliderCallback(emscripten::val callback)
{
    this->clearColliderCallback();
    this->m_jsCallback = emscripten::val(callback); // 存储 JS 函数
    Log::print("" + (this->_node->getID()) + "监听碰撞检测0 " + std::string(this->m_jsCallback.isUndefined() ? "undefined" : "valid"));
    // Log::print((this->_node->getID()) + "      "+ "this监听回调="  +  std::to_string(reinterpret_cast<uintptr_t>(this)));
}
#else
void ColliderBase::setColliderCallback(CollisionCallback callback)
{
    this->clearColliderCallback();
    this->onCollisionCallback = callback;
}
#endif

void ColliderBase::clearColliderCallback()
{
    #ifdef __EMSCRIPTEN__
        this->m_jsCallback = emscripten::val::undefined();
    #else
        this->onCollisionCallback = nullptr;
    #endif
}
bool ColliderBase::isOnCollider()
{

#ifdef __EMSCRIPTEN__
    // Log::print((this->_node->getID()) + "      "+ "this是否监听了回调="+ std::to_string(reinterpret_cast<uintptr_t>(this)));
    // Log::print("" + (this->_node->getID()) + "进行碰撞检测监听....." + std::string(this->m_jsCallback.isUndefined() ? "undefined" : "valid"));
    if (!this->m_jsCallback.isUndefined())
    {
        // Log::print("0进行碰撞检测监听.....");
        return true;
    }
    // Log::print("0未进行碰撞检测监听.....");
#else
    if (this->onCollisionCallback != nullptr)
    {
        // Log::print("1进行碰撞检测监听.....");
        return true;
    }
    // Log::print("1未进行碰撞检测监听.....");
#endif
    return false;
}
float ColliderBase::colliderTest(ColliderBase *collider)
{
    Log::print("ColliderBase colliderTest");
    return -1;
}
void ColliderBase::emitColliderCall(ColliderBase *collider)
{

#ifdef __EMSCRIPTEN__
    if (!m_jsCallback.isUndefined() && collider->getNode() != nullptr)
    {
        this->m_jsCallback(collider->getNode()->getID()); // 直接调用 JS 函数
    }
#else
    if (this->onCollisionCallback != nullptr && collider->getNode() != nullptr)
    {
        this->onCollisionCallback(collider->getNode()->getID());
    }
#endif
}
void ColliderBase::destroy(){
    Physics::colliders.erase(this->_node->getID());
    delete this->_aabb;
    this->_aabb=nullptr;
}

ColliderBase::~ColliderBase()
{
   
}